package com.ys.utils.help;

import cn.hutool.core.util.IdUtil;
import com.ys.base.BaseConstants;
import com.ys.base.EnumType;
import com.ys.utils.base.http.McodeHandler;
import com.ys.utils.base.j2se.DateUtil;
import com.ys.utils.base.j2se.JsonUtil;
import com.ys.utils.base.j2se.Logger;
import com.ys.utils.base.j2se.StringHandler;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.GroupKey;
import com.ys.utils.redis.key.UserKey;
import com.ys.utils.spring.config.SystemError;
import com.ys.web.user.friends.mapper.GroupInfoMapper;
import com.ys.web.user.friends.po.BaseGroupInfoPO;
import com.ys.web.verticel.WebSocketVerticle;
import com.ys.web.ws.bean.MessageNoticeBean;
import com.ys.web.ws.bean.MessageNoticeEntity;
import com.ys.web.ws.bean.MessageResponseBean;
import com.ys.web.ws.manager.ChatObjectManager;
import io.vertx.core.http.ServerWebSocket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @author quxinjun
 * @version 1.0.0
 * @ClassName GroupUtils.java
 * @Description 群组帮助类
 * @createTime 2021年05月26日 15:00:00
 */
@Slf4j
@Component
public class GroupUtils {

    @Autowired
    private GroupInfoMapper groupInfoMapper;

    private static GroupInfoMapper groupInfoMapperStatic;

    public static void sendCurrentOnLine(MessageResponseBean response, String toId) {
        ServerWebSocket serverWebSocket = ChatObjectManager.getConnectionMap().get(toId);
        if (serverWebSocket != null) {
            boolean flag = false;
            try {
//                if (System.currentTimeMillis() - ChatObjectManager.getConnectionMapTime().get(toId) <= 1500) {
                    flag = WebSocketVerticle.sendMessage(serverWebSocket, response);
                    if (flag) {
                        return;
                    }
//                } else {
//                    serverWebSocket.close();
//                }
            } catch (Exception e) {
//                ChatObjectManager.removeChatMapByKey(McodeHandler.to32Radix(Long.parseLong(toId)));
            }
        }
    }

    public static MessageNoticeEntity parsData(MessageNoticeBean messageNoticeBean) {
        MessageNoticeEntity messageNoticeEntity = new MessageNoticeEntity();
        messageNoticeEntity.setMembers(JsonUtil.jsonToBean(messageNoticeBean.getMembers(), Set.class));
        messageNoticeEntity.setMessage(JsonUtil.jsonToBean(messageNoticeBean.getMessage(), MessageResponseBean.class));
        return messageNoticeEntity;
    }

    @PostConstruct
    public void init() {
        groupInfoMapperStatic = this.groupInfoMapper;
    }

    /**
     * @param toId     发送给谁的用户id
     * @param windowId 窗口id
     * @title sendIfAbsent
     * @description 发送通知，如果通知为发送成功，存在缓存中，用户上线后发出去
     * @author quxinjun
     * @updateTime 2021/5/25 10:28
     */
    public static void sendIfAbsent(MessageResponseBean response, String toId, String windowId) {
        response.setWindowId(windowId != null ? windowId : response.getWindowId());
        ServerWebSocket serverWebSocket = ChatObjectManager.getConnectionMap().get(McodeHandler.to32Radix(Long.parseLong(toId)));
        if (serverWebSocket != null) {
            boolean flag = false;
            try {
//                if (System.currentTimeMillis() - ChatObjectManager.getConnectionMapTime().get(McodeHandler.to32Radix(Long.parseLong(toId))) <= 1500) {
                    flag = WebSocketVerticle.sendMessage(serverWebSocket, response);
                    if (flag) {
                        return;
                    }
//                } else {
//                    serverWebSocket.close();
//                }
            } catch (Exception e) {
                Logger.error("发送推送消息异常：", e);
//                ChatObjectManager.removeChatMapByKey(McodeHandler.to32Radix(Long.parseLong(toId)));
            }
        }
        //截屏通知只发送在线信息
        if (response.getCode().equals(EnumType.MessageCode.MESSAGE_LAUNCH_SCREEN_HOST_NOTICE.getCode())) {
            return;
        }
        String key = UserKey.noticeKey(toId);
        Redis.list.lpush(key, JsonUtil.toJson(response));
    }

    /**
     * @param messageResponseBean
     * @param o
     * @title sendIfAbsentForClear
     * @description
     * @author quxinjun
     * @updateTime 2021/6/7 10:33
     */
    public static void sendIfAbsentForClear(MessageResponseBean messageResponseBean, String o) {
        ServerWebSocket serverWebSocket = ChatObjectManager.getConnectionMap().get(McodeHandler.to32Radix(Long.parseLong(o)));
        if (serverWebSocket != null) {
            boolean flag = WebSocketVerticle.sendMessage(serverWebSocket, messageResponseBean);
            if (flag) {
                return;
            }
        }
        String key = UserKey.messageClearKey(o);
        Redis.hash.hSet(key, messageResponseBean.getGroupId(), JsonUtil.toJson(messageResponseBean));
        Redis.key.setKeyTimeout(key, BaseConstants.SAVE_TIME);
    }

    /**
     * @param ids     发给哪些人
     * @param uid     谁发送的
     * @param groupId 组id
     * @param code    通知类型
     * @title sendIds
     * @description 发送通知
     * @author quxinjun
     * @updateTime 2021/5/14 17:14
     */
    public static void sendIds(List<String> ids, Long uid, String groupId, int code, String data) {
        MessageResponseBean messageResponseBean = new MessageResponseBean();

        messageResponseBean.setMessageId(IdUtil.simpleUUID());
        messageResponseBean.setCreateTime(DateUtil.getDate(new Date(), BaseConstants.BASE_FORMAT));
        messageResponseBean.setGroupId(groupId);
        messageResponseBean.setGroupName(UserUtils.getGroupCacheNameByGroupId(groupId));
        messageResponseBean.setCode(code);
        messageResponseBean.setGroupPic(groupId != null ? (StringHandler.isNotEmpty(GroupUtils.getCacheGroupInfo(groupId)) ? GroupUtils.getCacheGroupInfo(groupId).getPic() : null) : null);
        messageResponseBean.setWindowId(groupId != null ? BaseConstants.GROUP_PREFIX + groupId : BaseConstants.SINGLE_PREFIX + McodeHandler.to32Radix(uid));
        messageResponseBean.setData(data);
//        System.out.println(messageResponseBean.getData());
        ids.forEach(o -> {
            ServerWebSocket serverWebSocket = ChatObjectManager.getConnectionMap().get(McodeHandler.to32Radix(Long.parseLong(o)));
            if (serverWebSocket != null) {
//                String str = UserUtils.getMessageResponseList(String.valueOf(uid), String.valueOf(groupId), code, data, null);
                String str = JsonUtil.toJson(new ArrayList<>(Collections.singletonList(messageResponseBean)));
                serverWebSocket.writeTextMessage(str);
            }
        });
    }

    /**
     * @param uid     操作用户id
     * @param groupId 群组id
     * @title validateIsMaster
     * @description 验证用户是不是群主（从缓存中验证）
     * @author quxinjun
     * @updateTime 2021/5/26 15:15
     * @return: boolean
     */
    public static void validateIsMaster(Long uid, String groupId) {
        Set<String> range = Redis.zSet.range(GroupKey.groupMembersKey(groupId), 0, -1);
        if (StringHandler.isNotEmpty(range) && !range.isEmpty()) {
            String masterId = range.iterator().next();
            if (masterId.equals(String.valueOf(uid))) {
                return;
            }
        }
        SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您不是群主，无法操作");
    }

    /**
     * @param uid     操作人id
     * @param groupId 群组id
     * @title validateIsManager
     * @description 验证是不是管理员
     * @author quxinjun
     * @updateTime 2021/5/27 17:51
     */
    public static void validateIsManager(Long uid, String groupId) {
        Set<String> range = Redis.zSet.rangeByScore(GroupKey.groupMembersKey(groupId), EnumType.GroupIdentity.MASTER.getCode().doubleValue(), EnumType.GroupIdentity.MANAGER.getCode().doubleValue());
        if (StringHandler.isNotEmpty(range) && !range.isEmpty()) {
            if (range.contains(String.valueOf(uid))) {
                return;
            }
        }
        SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您不是群主或管理员，无法操作");
    }

    /**
     * @param uid     操作人id
     * @param groupId 群组id
     * @title validateIsManager
     * @description 验证是不是管理员
     * @author quxinjun
     * @updateTime 2021/5/27 17:51
     */
    public static boolean isManager(long uid, String groupId) {
        Set<String> range = Redis.zSet.rangeByScore(GroupKey.groupMembersKey(groupId), EnumType.GroupIdentity.MASTER.getCode().doubleValue(), EnumType.GroupIdentity.MANAGER.getCode().doubleValue());
        if (StringHandler.isNotEmpty(range) && !range.isEmpty()) {
            return range.contains(String.valueOf(uid));
        }
        return false;
    }

    public static String getInviteNotice(String groupId, String uid) {
        //获取邀请人名称
        String title = null;
        String inviteName = UserUtils.getCacheUser(uid).getNickName();
        //判断邀请人和群主是不是一个人
        String masterId = null;
        if (Redis.key.exists(GroupKey.groupMembersKey(groupId))) {
            masterId = Redis.zSet.range(GroupKey.groupMembersKey(groupId), 0, -1).iterator().next();
        }
        if (StringHandler.isNotEmpty(masterId)) {
            if (!uid.equals(masterId)) {
                title = String.format(TipUtils.GROUP_INVITE_TITLE_2, inviteName, UserUtils.getCacheUser(masterId).getNickName());
            } else {
                title = String.format(TipUtils.GROUP_INVITE_TITLE_1, inviteName);
            }
        } else {
            title = String.format(TipUtils.GROUP_INVITE_TITLE_1, inviteName);
        }

        Map<String, String> result = new HashMap<>(16);

        result.put("title", title);
        result.put("groupPic", Objects.requireNonNull(getCacheGroupInfo(groupId)).getPic());

        return JsonUtil.toJson(result);
    }

    /**
     * @param groupId
     * @title isInGroup
     * @description 判断用户是不是已经在群内
     * @author quxinjun
     * @updateTime 2021/6/2 11:32
     * @return: java.lang.Boolean
     */
    public static Boolean isInGroup(String groupId, String uid) {
        Set<String> range = Redis.zSet.range(GroupKey.groupMembersKey(groupId), 0, -1);
        return range.contains(uid);
    }


    /**
     * @param groupId
     * @title getCacheGroupInfo
     * @description 获取缓存中的群组信息
     * @author quxinjun
     * @updateTime 2021/6/2 14:15
     * @return: com.ys.web.user.friends.po.BaseGroupInfoPO
     */
    public static BaseGroupInfoPO getCacheGroupInfo(String groupId) {
        String key = GroupKey.groupInfoKey(groupId);
        if (!Redis.key.exists(key)) {
            BaseGroupInfoPO baseGroupInfoPO = groupInfoMapperStatic.selectByPrimaryKey(groupId);
            if (baseGroupInfoPO != null && baseGroupInfoPO.getStatus()) {
                return baseGroupInfoPO;
            }else{
                SystemError.wrapBs("500","群信息异常");
                return null;
            }
        } else {
            return JsonUtil.jsonToBean(Redis.str.get(key), BaseGroupInfoPO.class);
        }
    }
}
